package com.ruoyi.web.controller.system

import com.ruoyi.common.annotation.Log
import com.ruoyi.common.core.controller.BaseController
import com.ruoyi.common.core.domain.AjaxResult
import com.ruoyi.common.core.domain.entity.SysDept
import com.ruoyi.common.core.domain.entity.SysRole
import com.ruoyi.common.core.domain.entity.SysUser
import com.ruoyi.common.core.page.TableDataInfo
import com.ruoyi.common.enums.BusinessType
import com.ruoyi.common.utils.MyStringUtils
import com.ruoyi.common.utils.SecurityUtils
import com.ruoyi.common.utils.poi.ExcelUtil
import com.ruoyi.system.service.ISysDeptService
import com.ruoyi.system.service.ISysPostService
import com.ruoyi.system.service.ISysRoleService
import com.ruoyi.system.service.ISysUserService
import org.apache.commons.lang3.ArrayUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
import javax.servlet.http.HttpServletResponse

/**
 * 用户信息
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/user")
open class SysUserController : BaseController() {

    @Autowired
    private lateinit var roleService: ISysRoleService
    @Autowired
    private lateinit var postService: ISysPostService
    @Autowired
    private lateinit var userService: ISysUserService
    @Autowired
    private lateinit var deptService: ISysDeptService
    /**
     * 获取用户列表
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/list")
    open fun list(user: SysUser): TableDataInfo {
        startPage()
        val list = userService.selectUserList(user)
        return getDataTable(list)
    }

    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:user:export')")
    @PostMapping("/export")
    open  fun export(response: HttpServletResponse, user: SysUser) {
        val list = userService.selectUserList(user)
        val util: ExcelUtil<SysUser> = ExcelUtil(SysUser::class.java)
        util.exportExcel(response, list, "用户数据")
    }

    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('system:user:import')")
    @PostMapping("/importData")
    @Throws(Exception::class)
    open  fun importData(file: MultipartFile, updateSupport: Boolean): AjaxResult {
        val util: ExcelUtil<SysUser> = ExcelUtil(SysUser::class.java)
        val userList= util.importExcel(file.inputStream)
        val operName: String = username
        val message: String = userService.importUser(userList, updateSupport, operName)
        return success(message)
    }

    @PostMapping("/importTemplate")
    open  fun importTemplate(response: HttpServletResponse) {
        val util: ExcelUtil<SysUser> = ExcelUtil(SysUser::class.java)
        util.importTemplateExcel(response, "用户数据")
    }

    /**
     * 根据用户编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @GetMapping(value = ["/", "/{userId}"])
    open  fun getInfo(@PathVariable(value = "userId", required = false) userId: Long?): AjaxResult {
        userService.checkUserDataScope(userId)
        val ajax: AjaxResult = AjaxResult.success()
        val roles= roleService.selectRoleAll()
        ajax["roles"] = if (SysUser.isAdmin(userId)) roles else roles.filter { r -> !r.isAdmin }.toMutableList()
        ajax["posts"] = postService.selectPostAll()
        if (MyStringUtils.isNotNull(userId)) {
            val sysUser: SysUser? = userService.selectUserById(userId)
            if(sysUser!=null){
                ajax[AjaxResult.DATA_TAG] = sysUser
                ajax["postIds"] = postService.selectPostListByUserId(userId)
                if(sysUser.roles!=null){
                    ajax["roleIds"] = sysUser.roles!!.map(SysRole::roleId).toMutableList()
                }
            }

        }
        return ajax
    }

    /**
     * 新增用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping
    open  fun add(@Validated @RequestBody user: SysUser): AjaxResult {
        if (!userService.checkUserNameUnique(user)) {
            return error("新增用户'" + user.userName + "'失败，登录账号已存在")
        } else if (MyStringUtils.isNotEmpty(user.phonenumber) && !userService.checkPhoneUnique(user)) {
            return error("新增用户'" + user.userName + "'失败，手机号码已存在")
        } else if (MyStringUtils.isNotEmpty(user.email) && !userService.checkEmailUnique(user)) {
            return error("新增用户'" + user.userName + "'失败，邮箱账号已存在")
        }
        user.createBy=username
        user.password=SecurityUtils.encryptPassword(user.password)
        return toAjax(userService.insertUser(user))
    }

    /**
     * 修改用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    open  fun edit(@Validated @RequestBody user: SysUser): AjaxResult {
        userService.checkUserAllowed(user)
        userService.checkUserDataScope(user.userId)
        if (!userService.checkUserNameUnique(user)) {
            return error("修改用户'" + user.userName + "'失败，登录账号已存在")
        } else if (MyStringUtils.isNotEmpty(user.phonenumber) && !userService.checkPhoneUnique(user)) {
            return error("修改用户'" + user.userName + "'失败，手机号码已存在")
        } else if (MyStringUtils.isNotEmpty(user.email) && !userService.checkEmailUnique(user)) {
            return error("修改用户'" + user.userName + "'失败，邮箱账号已存在")
        }
        user.updateBy=username
        return toAjax(userService.updateUser(user))
    }

    /**
     * 删除用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:remove')")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    open   fun remove(@PathVariable userIds: Array<Long>): AjaxResult {
        return if (ArrayUtils.contains(userIds, userId)) {
            error("当前用户不能删除")
        } else toAjax(userService.deleteUserByIds(userIds))
    }

    /**
     * 重置密码
     */
    @PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    open  fun resetPwd(@RequestBody user: SysUser): AjaxResult {
        userService.checkUserAllowed(user)
        userService.checkUserDataScope(user.userId)
        user.password=SecurityUtils.encryptPassword(user.password)
        user.updateBy=username
        return toAjax(userService.resetPwd(user))
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    open  fun changeStatus(@RequestBody user: SysUser): AjaxResult {
        userService.checkUserAllowed(user)
        userService.checkUserDataScope(user.userId)
        user.updateBy=username
        return toAjax(userService.updateUserStatus(user))
    }

    /**
     * 根据用户编号获取授权角色
     */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @GetMapping("/authRole/{userId}")
    open  fun authRole(@PathVariable("userId") userId: Long): AjaxResult {
        val ajax: AjaxResult = AjaxResult.success()
        val user: SysUser? = userService.selectUserById(userId)
        val roles = roleService.selectRolesByUserId(userId)
        if(user!=null){
            ajax["user"] = user
        }
        ajax["roles"] = if (SysUser.isAdmin(userId)) roles else roles.filter { r -> !r.isAdmin }.toMutableList()
        return ajax
    }

    /**
     * 用户授权角色
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PutMapping("/authRole")
    open  fun insertAuthRole(userId: Long?, roleIds: Array<Long>?): AjaxResult {
        userService.checkUserDataScope(userId)
        userService.insertUserAuth(userId, roleIds)
        return success()
    }

    /**
     * 获取部门树列表
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/deptTree")
    open  fun deptTree(dept: SysDept): AjaxResult {
        return success(deptService.selectDeptTreeList(dept))
    }
}
